//
//  ScanCodeView.m
//  YuanXinCamera
//
//  Created by 晏德智 on 2016/11/11.
//  Copyright © 2016年 晏德智. All rights reserved.
//

#import "ScanCodeView.h"
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

#import <React/RCTAutoInsetsProtocol.h>
#import <React/RCTLog.h>
#import <React/RCTUtils.h>
#import <React/RCTView.h>
#import "UIView+React.h"

#import "ScanCodeMaskView.h"

@interface ScanCodeView () <AVCaptureMetadataOutputObjectsDelegate, RCTAutoInsetsProtocol>

@property (nonatomic, strong) AVCaptureSession *session;

@property (nonatomic, strong) AVCaptureVideoPreviewLayer *avLayer;

@property (nonatomic, strong) AVCaptureMetadataOutput *output;

@property (nonatomic, strong) ScanCodeMaskView   *maskView;

@property (nonatomic, assign) BOOL isFlashOpen;

@property (nonatomic, assign) BOOL isOpen;

@property (nonatomic, assign) BOOL isInit;

@end

@implementation ScanCodeView

@synthesize avLayer   =    _avLayer;
@synthesize output  =    _output;
@synthesize autoStartRunning = _autoStartRunning;
@synthesize scanSize = _scanSize;
@synthesize maskView = _maskView;

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _avLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
        _avLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        [self.layer insertSublayer:_avLayer atIndex:0];
        
    }
    return self;
}


RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)

- (void)dealloc
{
    [_session removeOutput:_output];
    [_output setMetadataObjectsDelegate:nil queue:dispatch_get_main_queue()];
    _output = nil;
    [_avLayer removeFromSuperlayer];
    _avLayer =nil;
    _session =nil;
    [_maskView removeFromSuperview];
    _maskView =nil;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
}

- (void)setContentInset:(UIEdgeInsets)contentInset
{
    _contentInset = contentInset;
}

- (void)setAutoStartRunning:(BOOL)autoStartRunning
{
    _autoStartRunning=autoStartRunning;
}

- (void)setScanSize:(CGSize)size{
    if(_scanSize.height == size.height && _scanSize.width == size.width){
        
    }else{
        _scanSize = size;
    }
}

/*
 - (void)refreshContentInset
 {
 }
 */

#pragma mark - Getter

- (AVCaptureMetadataOutput *)output {
    if(!_output){
        //创建输出流
        _output = [[AVCaptureMetadataOutput alloc] init];
        //设置代理 在主线程里刷新
        [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        //设置扫描区域的比例
        CGFloat width = _scanSize.width / CGRectGetHeight(self.frame);
        CGFloat height = _scanSize.height / CGRectGetWidth(self.frame);
        
        _output.rectOfInterest = CGRectMake((1 - width) / 2, (1- height) / 2, width, height);
        //设置扫码支持的编码格式(这里设置条形码和二维码兼容)
        _output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,
                                        AVMetadataObjectTypeEAN13Code,
                                        AVMetadataObjectTypeEAN8Code,
                                        AVMetadataObjectTypeCode128Code];
    }
    return _output;
}

- (AVCaptureSession *)session
{
    if (!_session)
    {
        _session  = [[AVCaptureSession alloc] init];
    }
    
    return _session;
}

#pragma mark - method
- (void)stopRunning {
    
    if(_session && _isOpen){
        [_session stopRunning];
        _isOpen = NO;
    }
}

- (void)startRunning {
    if(_session && !_isOpen){
        [_session startRunning];
        _isOpen = YES;
    }
}

- (void)flashOpen{
    if(!self.isFlashOpen){
        self.isFlashOpen = YES;
        [self flashSwitch:self.isFlashOpen];
    }
}

- (void)flashClose{
    if(self.isFlashOpen){
        self.isFlashOpen = NO;
        [self flashSwitch:self.isFlashOpen];
    }
}

/**
 * 闪光灯开关管理
 */
- (void)flashSwitch:(BOOL)flashSwitch {
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    if ([device hasTorch] && [device hasFlash])
    {
        [device lockForConfiguration:nil];
        
        if (flashSwitch)
        {
            device.torchMode = AVCaptureTorchModeOn;
            device.flashMode = AVCaptureFlashModeOn;
        }
        else
        {
            device.torchMode = AVCaptureTorchModeOff;
            device.flashMode = AVCaptureFlashModeOff;
        }
        
        [device unlockForConfiguration];
    }
}



- (void)sendError:(int)code description:(NSString *)errorDescription{
    if(_onError){
        _onError(@{
                   @"code": @(code),
                   @"description": errorDescription,
                   });
    }
}

- (void)reactSetFrame:(CGRect)frame
{
    [super reactSetFrame:frame];
    _avLayer.frame = CGRectMake(0,0,CGRectGetWidth(frame),CGRectGetHeight(frame));
    if(!self.isInit){
        self.isInit = YES;
        _maskView = [[ScanCodeMaskView alloc] initWithFrame:_avLayer.frame];
        _maskView.pickingFieldWidth  = self.scanSize.width;
        _maskView.pickingFieldHeight = self.scanSize.height;
        if(_maskViewBackgroundColor){
            _maskView.backgroundColor = _maskViewBackgroundColor;
        }
        
        [self addSubview:_maskView];
        AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        // NSString *tips = NSLocalizedString(@"AVAuthorization", @"您没有权限访问相机");
        if(status == AVAuthorizationStatusAuthorized) {
            //获取摄像设备
            AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
            
            NSError *error;
            //创建输入流
            AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
            if (error || !input)
            {
                return ;
            }
            [self.session beginConfiguration];
            //高质量采集率
            [self.session setSessionPreset:AVCaptureSessionPresetHigh];
            if ([self.session canAddInput:input]){
                [self.session addInput:input];
            }
            
            //创建输出流
            AVCaptureMetadataOutput *_output = [[AVCaptureMetadataOutput alloc] init];
            //设置代理 在主线程里刷新
            [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
            
            if ([self.session canAddOutput:_output]){
                [self.session addOutput:_output];
            }
            //设置扫描区域的比例
            CGFloat width = _scanSize.width / CGRectGetHeight(frame);
            CGFloat height = _scanSize.height / CGRectGetWidth(frame);
            _output.rectOfInterest = CGRectMake((1 - width) / 2, (1- height) / 2, width, height);
            //设置扫码支持的编码格式(这里设置条形码和二维码兼容)
            _output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,
                                            AVMetadataObjectTypeEAN13Code,
                                            AVMetadataObjectTypeEAN8Code,
                                            AVMetadataObjectTypeCode128Code];
            [self.session commitConfiguration];
            if(self.autoStartRunning){
                [self startRunning];
            }
        }else{
            NSString *tips = NSLocalizedString(@"AVAuthorization", @"您没有权限访问相机");
            [self sendError:0 description:tips];
        }
    }
}


#pragma mark - AVCaptureMetadataOutputObjectsDelegate
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    if (metadataObjects.count > 0)
    {
        [self stopRunning];
        
        AVMetadataMachineReadableCodeObject *metadata = [metadataObjects firstObject];
        
        if(_onCodeRead){
            _onCodeRead(@{
                          @"type": metadata.type,
                          @"data": metadata.stringValue,
                          @"bounds": @{
                                  @"origin": @{
                                          @"x": [NSString stringWithFormat:@"%f", metadata.bounds.origin.x],
                                          @"y": [NSString stringWithFormat:@"%f", metadata.bounds.origin.y]
                                          },
                                  @"size": @{
                                          @"height": [NSString stringWithFormat:@"%f", metadata.bounds.size.height],
                                          @"width": [NSString stringWithFormat:@"%f", metadata.bounds.size.width],
                                          }
                                  }
                          });
        }
        
    }
}

@end
